import { render, h, Directive } from 'vue'
import { Spin } from 'ant-design-vue'

const mount = (el: HTMLElement): void => {
  el.childNodes.forEach((item: any) => {
    item.style && (item.style.opacity = '0.3')
  })
  // 绑定节点下创建子节点
  let parent: HTMLElement | null = el.querySelector('#__LOADING_PARENT__')
  if (!parent) {
    parent = document.createElement('div')
    parent.style.position = 'relative'
    parent.id = '__LOADING_PARENT__'
    if (el.firstChild) {
      el.insertBefore(parent, el.firstChild)
    } else {
      el.appendChild(parent)
    }
  }
  parent.style.opacity = '1'
  const elStyle = window.getComputedStyle(el, null)
  const style = {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    position: 'absolute',
    flexDirection: 'column',
    left: `-${elStyle.paddingLeft}`,
    width: `${el.clientWidth}px`,
    height: `${el.clientHeight}px`,
    backgroundColor: 'rgba(128, 128, 128, 0)',
    color: 'var(--primary-color)',
    opacity: 1,
    zIndex: 1000
  }
  render(h(Spin, { class: 'directive-loading', tip: '加载中...', size: 'large', style }), parent)
}
const unmount = (el: HTMLElement) => {
  el.childNodes.forEach((item: any) => {
    item.style && (item.style.opacity = '1')
  })
  const loading: HTMLElement | null = el.querySelector('#__LOADING_PARENT__')
  if (!loading) return
  el.removeChild(loading)
}
export const loading: Directive = {
  // 在绑定元素的父组件 及他自己的所有子节点都挂载完成后调用
  mounted: (el: HTMLElement, binding: any) => {
    binding.value && mount(el)
  },
  // 在绑定元素的父组件 及他自己的所有子节点都更新后调用
  updated:
    (el: HTMLElement, binding: any) => {
      binding.value ? mount(el) : unmount(el)
    }
}
